package com.xof.phonecall

import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.PersistableBundle
import android.telecom.Call
import android.view.View
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.xof.phonecall.base.BaseActivity
import com.xof.phonecall.component.dialog.MessageDialog
import com.xof.phonecall.databinding.ActivityOutgoingCallBinding
import com.xof.phonecall.extipetrpide.startToNextActivityAndFinish
import com.xof.phonecall.helpipetrpide.UserStateHelp
import com.xof.phonecall.model.ToSavePhoneNumberStateTo
import com.xof.phonecall.telecom.MyCallManager
import com.xof.phonecall.valipetrpide.ValGlobalConstant
import com.xof.phonecall.valipetrpide.ValPoint
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import java.util.Date

class OutgoingCallActivity : BaseActivity() {

    lateinit var mActivityBinding: ActivityOutgoingCallBinding
    lateinit var mNextCallHandler: Handler
    lateinit var mPhoneNumber: String

    private val mCutdownSec = 5
    private var mCutdownSecFlow: Job? = null

    private var mGlobalCutdownSecFlow: Job? = null//全局监听倒计时
    private val mGlobalCutdownSec = 17280000//设置为200天的倒计时
    private val mGlobalRefetchPhoneNumberSec: Long = 120000//如果出错，60秒后再重拉接口
    private val mGlobalCallPhoneDelaySec: Long = 8000//获取到号码后，延迟7秒后再拨打电话


    lateinit var mCallBack: Call.Callback

    private val mViewModelUserStatus by lazy {
        ViewModelProvider(this).get(ViewModelUserStatus::class.java)
    }

    override fun onBindingViewModel(): List<ViewModel> {
        val list = mutableListOf<ViewModel>()
        list.add(mViewModelUserStatus)
        return list
    }

    override fun onBindingViewTag(): String {
        return ValPoint.OUTGOING.name
    }

    override fun onBindingContentView(): View {
        mActivityBinding = ActivityOutgoingCallBinding.inflate(layoutInflater)
        return mActivityBinding.root
    }

    @OptIn(DelicateCoroutinesApi::class)
    @SuppressLint("SetTextI18n")
    override fun onContentViewBinded() {
        try {
            //设置版本号
            mActivityBinding.tnbNavBar.setCenterText("Outgoing (R${ValGlobalConstant.VAL_APP_VERSION})")

            //保存当前页面
            MyApplication.outgoingCallActivity = this

            //全局倒计时
            startGlobalCutdown(lifecycleScope)

            //获取当前号码
            mPhoneNumber = intent.data?.schemeSpecificPart.toString()
            mActivityBinding.textCallNow.text =
                "To：${mPhoneNumber}"

            //初始化线程调用
            mNextCallHandler = Handler(Looper.getMainLooper())

            //获取下一个拨打的号码返回
            mViewModelUserStatus.LiveDataNextPhoneNumber.observe(this) {
                //重置错误状态
                updateErrorState()

                if (it.isSuccess) {
                    if (it.getOrNull() == null) {
                        updateStatus("获取号码错误，${mGlobalRefetchPhoneNumberSec / 1000}秒后重新获取\n")
                        updateStatus("${MyApplication.dateTimeFormatter.format(Date())}\n")
                    } else {
                        it.getOrNull()?.let { result ->
                            //更新状态
                            mViewModelUserStatus.updatePhoneNumberInfo(result)

                            if (result.mobile?.isNotBlank() == true) {
                                //更新提示状态
                                if (!mViewModelUserStatus.mIsManualStopCalling) {
                                    //更新目标号码展示
                                    mActivityBinding.textCallNow.text = "To：${result.mobile}"

                                    updateStatus("--> ${result.mobile}")
                                    startCutdown(lifecycleScope)

                                    //等待唤起
                                    mViewModelUserStatus.mDelayJob?.let { gJob ->
                                        if (gJob.isActive) {
                                            gJob.cancel()
                                        }
                                    }
                                    mViewModelUserStatus.mDelayJob = null

                                    mViewModelUserStatus.mDelayJob =
                                        CoroutineScope(Dispatchers.Main).launch {
                                            delay(mGlobalCallPhoneDelaySec)
                                            updateStatus("唤起成功")

                                            //如果手动停止，不做拨号动作
                                            if (mViewModelUserStatus.mIsManualStopCalling) {
                                                mActivityBinding.textCallNow.text =
                                                    "To：Stop Calling"
                                                updateStatus("已手动停止")
                                                updateStatus(
                                                    "${
                                                        MyApplication.dateTimeFormatter.format(
                                                            Date()
                                                        )
                                                    }\n"
                                                )
                                            } else {
                                                //重置错误状态
                                                //mViewModelUserStatus.mLastPhoneNumberIsNull = false

                                                //清空正在拨打标志
                                                MyCallManager.mPhoneNumber = ""

                                                //更新目标号码展示
                                                mActivityBinding.textCallNow.text =
                                                    "To：${result.mobile}"
                                                MyCallManager.unregisterCallback(mCallBack)
                                                mCallBack = getCallBack()
                                                MyCallManager.registerCallback(mCallBack)
                                                MyCallManager.call(
                                                    this@OutgoingCallActivity,
                                                    result.mobile
                                                )
                                            }
                                        }

//                                    mNextCallHandler.postDelayed({
//                                        println("更新目标号码展示")
//                                        if (mViewModelUserStatus.mIsManualStopCalling) {
//                                            mActivityBinding.textCallNow.text = "To：Stop Calling"
//                                            updateStatus("已手动停止")
//                                        } else {
//                                            //更新目标号码展示
//                                            mActivityBinding.textCallNow.text =
//                                                "To：${result.mobile}"
//                                            MyCallManager.call(this, result.mobile)
//                                        }
//                                    }, mGlobalCallPhoneDelaySec)
                                } else {
                                    mActivityBinding.textCallNow.text = "To：Stop Calling"
                                    updateStatus("已手动停止")
                                    updateStatus("${MyApplication.dateTimeFormatter.format(Date())}\n")
                                }
                            } else {
                                //更新目标号码展示
                                mActivityBinding.textCallNow.text = "To：No Call"
                                updateStatus("获取号码为空，${mGlobalRefetchPhoneNumberSec / 1000}秒后重新获取")
                                updateStatus("${MyApplication.dateTimeFormatter.format(Date())}\n")
                            }
                        }
                    }
                } else {
                    updateStatus("获取号码错误，${mGlobalRefetchPhoneNumberSec / 1000}秒后重新获取")
                    updateStatus("${MyApplication.dateTimeFormatter.format(Date())}\n")
                }
            }

            //保存拨打的号码的状态返回
            mViewModelUserStatus.LiveDataSavePhoneNumberState.observe(this) {
                //重置错误状态
                updateErrorState()
                //清空正在拨打标志
                MyCallManager.mPhoneNumber = ""

                if (it.isSuccess) {
                    updateStatus("保存拨打结果成功\n")
                } else {
                    updateStatus("保存拨打结果失败-接口返回失败\n")
                }
                mViewModelUserStatus.mCallCanActive = false
                if (mViewModelUserStatus.mIsManualStopCalling) {
                    updateStatus("已手动停止拨打号码")
                    updateStatus("${MyApplication.dateTimeFormatter.format(Date())}\n")
                } else {
                    mViewModelUserStatus.getNextPhoneNumber(false)
                }
            }

            //注册call状态回调
            mCallBack = getCallBack()
            MyCallManager.registerCallback(mCallBack)

            //显示当前登录用户
            mActivityBinding.textSysLoginName.text = "Account：${UserStateHelp.loginName}"

            //挂断当前电话
            mActivityBinding.tnbNavBar.setOnActionClickListener { direction ->
                when (direction) {
                    R.integer.NavbarActionLeft -> {
                        println("left action")
                        //清空正在拨打标志
                        MyCallManager.mPhoneNumber = ""
                        mViewModelUserStatus.mIsManualStopCalling =
                            (!mViewModelUserStatus.mIsManualStopCalling)
                        println("mIsManualStopCalling：${mViewModelUserStatus.mIsManualStopCalling}")

                        if (mViewModelUserStatus.mIsManualStopCalling) {
                            //重置错误状态
                            updateErrorState()
                            mActivityBinding.textCallNow.text = "To：Stop Calling"
                            mActivityBinding.tnbNavBar.setLeftImgRes(R.drawable.play)
                            mCutdownSecFlow?.cancel()
                            updateStatus("已手动停止")
                            updateStatus("${MyApplication.dateTimeFormatter.format(Date())}\n")

                        } else {
                            //重置错误状态
                            updateErrorState()
                            mActivityBinding.tnbNavBar.setLeftImgRes(R.drawable.stop)
                            updateStatus("开始拨打号码,排队中")
                        }
                        MyCallManager.reject()
                    }
                    R.integer.NavbarActionRight -> {
                        println("right action")
                        MessageDialog.showDialogipetrpide(
                            fragmentManager = supportFragmentManager,
                            message = "Are you sure to exit?",
                            cancel = "Cancel",
                            confirm = "Confirm"
                        ) {
                            mNextCallHandler.removeCallbacksAndMessages(null)
                            MyCallManager.reject()
                            UserStateHelp.logout()
                            val hashMap = HashMap<String, String>()
                            startToNextActivityAndFinish<LoginActivity>(params = hashMap)
                        }
                    }
                }
            }

            //获取下一个拨打的号码
            //清空正在拨打标志
            MyCallManager.mPhoneNumber = ""
            mViewModelUserStatus.getNextPhoneNumber(false)

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onDestroy() {
        println("====== 注销activity")
        mCutdownSecFlow?.cancel()
        mGlobalCutdownSecFlow?.cancel()
        super.onDestroy()

    }

    override fun onBackPressed() {
        println("====== 屏蔽返回操作")
    }

    override fun onPostCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onPostCreate(savedInstanceState, persistentState)
    }

    private fun getCallBack(): Call.Callback {

        return object : Call.Callback() {
            override fun onConnectionEvent(call: Call?, event: String?, extras: Bundle?) {
                super.onConnectionEvent(call, event, extras)
                println("onConnectionEvent: $event")
            }

            override fun onStateChanged(call: Call?, state: Int) {
                /*
                    Call states:
                     1   = Call.STATE_DIALING
                     2   = Call.STATE_RINGING
                     3   = Call.STATE_HOLDING
                     4   = Call.STATE_ACTIVE
                     7   = Call.STATE_DISCONNECTED
                     8   = Call.STATE_SELECT_PHONE_ACCOUNT
                     9   = Call.STATE_CONNECTING
                     10  = Call.STATE_DISCONNECTING
                     11  = Call.STATE_PULLING_CALL
                */
                println("=====onStateChanged:$state")
                super.onStateChanged(call, state)

                //如果是来电的挂断，不处理
                val detectMobile = call?.details?.handle?.schemeSpecificPart.toString()


                //更新提示语状态
                var gStateDes = getStatusDes(state)
                updateStatus(gStateDes)

                //如果接通了，直接挂断
                if (state == Call.STATE_ACTIVE) {
                    mViewModelUserStatus.mCallCanActive = true
                    updateStatus("成功接听")
                    //清空正在拨打标志
                    MyCallManager.mPhoneNumber = ""
                    //挂断
                    MyCallManager.reject()
                }

                if (10 == state) {
                    //清空正在拨打标志
                    MyCallManager.mPhoneNumber = ""
                }

                if (7 == state) {
                    //请求接口，保存状态
                    println("====== 请求接口，保存状态，拨打下一个号码")
                    updateStatus("拨打结束")

                    //记录挂断时间
                    mViewModelUserStatus.mLastValidRejectTime = System.currentTimeMillis()

                    //清空正在拨打标志
                    MyCallManager.mPhoneNumber = ""

                    var gState: String = state.toString()
                    val tempIsActive = mViewModelUserStatus.mCallCanActive
                    if (tempIsActive) {
                        gState = Call.STATE_ACTIVE.toString()
                        gStateDes = getStatusDes(Call.STATE_ACTIVE)
                    }

                    //保存拨打的号码的状态
                    val params = ToSavePhoneNumberStateTo(
                        mobile = mViewModelUserStatus.mCallPhoneNumber,
                        mobileType = mViewModelUserStatus.mCallPhoneType,
                        orderId = mViewModelUserStatus.mCallOrderId,
                        product = mViewModelUserStatus.mCallProduct,
                        userId = mViewModelUserStatus.mCallUserId,
                        result = gState,
                        remark = gStateDes,
                    )
                    //更新接听状态
                    mViewModelUserStatus.mCallCanActive = false

                    if (params.isValid()) {
                        mViewModelUserStatus.savePhoneNumberState(params)
                    } else {
                        var errTips = "保存拨打结果失败-请求参数不合法\n"
                        if (params.mobile.isBlank()) {
                            errTips += ("mobile isBlank\n")
                        }
                        if (params.orderId.isBlank()) {
                            errTips += ("orderId isBlank\n")
                        }
                        if (params.userId.isBlank()) {
                            errTips += ("userId isBlank\n")
                        }
                        if (params.mobileType.isBlank()) {
                            errTips += ("mobileType isBlank\n")
                        }
                        if (params.product.isBlank()) {
                            errTips += ("product isBlank\n")
                        }
                        if (params.result.isBlank()) {
                            errTips += ("result isBlank\n")
                        }
                        updateStatus(errTips)
                    }
                }

                //更新状态
                updateErrorStateNotWithCallActive()
            }
        }
    }

    /** 转化结果码 */
    fun getStatusDes(state: Int): String {
        when (state) {
            1 -> {
                return "状态:外拔呼叫中..."
            }
            2 -> {
                return "状态:来电响铃中..."
            }
            3 -> {
                return "状态:本机接听中..."
            }
            4 -> {
                return "状态:通话中..."
            }
            7 -> {
                return "状态:已经断开连接..."
            }
            8 -> {
                return "状态:选择手机账号..."
            }
            9 -> {
                return "状态:连接中..."
            }
            10 -> {
                return "状态:正在断开连接..."
            }
            11 -> {
                return "状态:正在尝试建立连接..."
            }
        }
        return "状态:未知..."
    }

    /** 更新显示滚动内容 */
    fun updateStatus(addContent: String) {
        var status = mActivityBinding.textCallStatus.text.toString()
        if (status.length > 1500) {
            status = ": $addContent"
        } else {
            if (status.isBlank()) {
                status = ": $addContent"
            } else {
                status += "\n"
                status += ": $addContent"
            }
        }
        runOnUiThread {
            mActivityBinding.textCallStatus.text = status
            mActivityBinding.nsvScrollView.post {
                mActivityBinding.nsvScrollView.fullScroll(View.FOCUS_DOWN)
            }
        }
    }

    /** 重置错误状态 */
    fun updateErrorState() {
        mViewModelUserStatus.mIsFetchingPhoneNumber = false
        mViewModelUserStatus.mCallCanActive = false
        mViewModelUserStatus.mLastPhoneNumberIsNull = true
        mViewModelUserStatus.updatePhoneNumberInfo(null)
        mNextCallHandler.removeCallbacksAndMessages(null)
    }

    /** 重置错误状态-不包括通话状态 */
    fun updateErrorStateNotWithCallActive() {
        mViewModelUserStatus.mIsFetchingPhoneNumber = false
        mViewModelUserStatus.mLastPhoneNumberIsNull = true
        mNextCallHandler.removeCallbacksAndMessages(null)
    }

    @SuppressLint("SetTextI18n")
    fun startCutdown(scopemoringsente: CoroutineScope) {
        mCutdownSecFlow?.cancel()
        mCutdownSecFlow =
            cutdownFlow(
                scope = scopemoringsente,
                onTick = {
                    if (it == 0) {
                        mCutdownSecFlow?.cancel()
                    } else {
                        updateStatus(it.toString())
                    }
                },
                onFinish = {

                })
    }

    private fun cutdownFlow(
        scope: CoroutineScope,
        onTick: (Int) -> Unit,
        onFinish: () -> Unit,
    ): Job {
        return flow {
            for (tickSec in mCutdownSec downTo 0) {
                emit(tickSec)
                if (tickSec != 0) {
                    delay(1000)
                }
            }
        }.flowOn(Dispatchers.Main)
            .onEach { onTick.invoke(it) }
            .onCompletion { onFinish.invoke() }
            .launchIn(scope)
    }

    /** 注册一个长时间的轮询监听 */
    @SuppressLint("SetTextI18n")
    fun startGlobalCutdown(scopemoringsente: CoroutineScope) {
        mGlobalCutdownSecFlow?.cancel()
        mGlobalCutdownSecFlow =
            globalCutdownFlow(
                scope = scopemoringsente,
                onTick = {
                    println("startGlobalCutdown $it")
                    if (it == 0) {
                        mGlobalCutdownSecFlow?.cancel()
                    } else {
                        println("Global Sec：${mViewModelUserStatus.mIsManualStopCalling}-${mViewModelUserStatus.mLastPhoneNumberIsNull}-${mViewModelUserStatus.mIsFetchingPhoneNumber}")
                        val isCalling = MyCallManager.mPhoneNumber.isNotBlank()
                        updateStatus("轮询状态:stop:${mViewModelUserStatus.mIsManualStopCalling}, calling:${isCalling}, fetching:${mViewModelUserStatus.mIsFetchingPhoneNumber}\n")

                        //判断现在是否需要再次轮询
                        //1、非手动停止
                        //2、上一次号码为空
                        //3、非在获取号码的进度中
                        //4、如果上次一直在获取时间超过5分钟
                        if (it != mGlobalCutdownSec) {
                            if (!mViewModelUserStatus.mIsManualStopCalling) {
                                if (!mViewModelUserStatus.mIsFetchingPhoneNumber) {
                                    //清空正在拨打标志
                                    MyCallManager.mPhoneNumber = ""
                                    mViewModelUserStatus.getNextPhoneNumber(showLoading = false)
                                } else {
                                    //如果一直在通话超过3分钟，直接挂断
                                    val curTime = System.currentTimeMillis()
                                    val edgeRejectTime =
                                        (curTime - mViewModelUserStatus.mLastValidRejectTime)
                                    val maxCallingSec = (3 * 60 * 1000)
                                    if (edgeRejectTime > maxCallingSec) {
                                        MyCallManager.reject()
                                    }

                                    //如果一直在获取超过5分钟，重置状态mIsFetchingPhoneNumber=false
                                    val edgeTime =
                                        (curTime - mViewModelUserStatus.mLastValidFetchingTime)
                                    val compareSec = (5 * 60 * 1000)
                                    if (edgeTime >= compareSec) {
                                        updateStatus("轮询状态:获取号码接口超过5分钟没响应，重新获取\n")
                                        mViewModelUserStatus.mIsFetchingPhoneNumber = false
                                        //清空正在拨打标志
                                        MyCallManager.mPhoneNumber = ""
                                        mViewModelUserStatus.getNextPhoneNumber(showLoading = false)
                                    } else {
                                        updateStatus("轮询状态:获取号码接口未响应，继续等待\n")
                                    }
                                }
                            }
                        }
                    }
                },
                onFinish = {

                })
    }

    /** 全局轮询 */
    private fun globalCutdownFlow(
        scope: CoroutineScope,
        onTick: (Int) -> Unit,
        onFinish: () -> Unit,
    ): Job {
        return flow {
            for (tickSec in mGlobalCutdownSec downTo 0) {
                emit(tickSec)
                if (tickSec != 0) {
                    delay(mGlobalRefetchPhoneNumberSec)
                }
            }
        }.flowOn(Dispatchers.IO)
            .onEach { onTick.invoke(it) }
            .onCompletion { onFinish.invoke() }
            .launchIn(scope)
    }
}